package org.dallasrowing.logbook.ui.controller;

import java.util.List;

import org.dallasrowing.logbook.ui.view.BeanEditorWidget;
import org.dallasrowing.model.dao.DAOException;

public abstract class BeanEditorControllerImpl<T> implements BeanEditorController {

	private BeanEditorWidget<T> widget;
	private AdminWindowController parentController;

	private boolean createNew = false;
	private List<T> beans;

	public BeanEditorControllerImpl(AdminWindowController parentController, BeanEditorWidget<T> widget) {
		this.widget = widget;
		this.parentController = parentController;
	}

	protected void init() {
		populateBeans();
		registerListeners();
	}

	protected abstract void updateBean(T bean) throws DAOException;

	protected abstract T newBean() throws DAOException;

	protected abstract void createBean(T bean) throws DAOException;

	protected abstract List<T> getAllBeans() throws DAOException;

	protected void updateClicked() {
		try {
			int selected = widget.getSelectedBean();
			T bean = beans.get(selected);
			widget.updateBean(bean);
			updateBean(bean);
		} catch (DAOException e) {
			parentController.showError(e);
		}
		parentController.close();
	}

	protected void createNewBean() {
		try{
			T b = newBean();
			widget.updateBean(b);
			createBean(b);
		} catch (DAOException e) {
			parentController.showError(e);
		}
		parentController.close();

	}

	protected void createNewClicked() {
		this.createNew = true;
		widget.enableNew();
	}

	protected void beanSelected() {
		int index = widget.getSelectedBean();

		widget.enableUpdate();
		createNew = false;

		T bean = beans.get(index);
		widget.setBean(bean);
	}

	protected void populateBeans() {
		try {
			beans = getAllBeans();
			widget.fillBeans(beans);
		} catch (DAOException e) {
			parentController.showError(e);
		}
	}

	private void registerListeners() {
		widget.onBeanSelected(new Runnable() {
			public void run() {
				beanSelected();
			}
		});
		widget.onCloseClicked(new Runnable() {
			public void run() {
				parentController.close();
			}
		});
		widget.onCreateNewClicked(new Runnable() {
			public void run() {
				createNewClicked();
			}
		});
		widget.onUpdateClicked(new Runnable() {
			public void run() {
				if (createNew)
					createNewBean();
				else
					updateClicked();
			}
		});
	}

}
